package com.markhsiu.tools;

import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.security.SecureRandom;
import java.text.DecimalFormat;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 数字处理工具类
 *
 * 注：商品购买成功后，返还积分时按照 1元 = 1积分 的规则返还
 *    购买商品消耗积分时，按照 1积分 = 1分 的规则计算
 *
 */
public class NumberUtil {

    //默认保留的小数位数
    public static int DEFAULT_DIV_SCALE = 2;
    public static int ONE_SCALE = 1;
    public static int INTEGER_SCALE = 0;
    public static String YUAN_FORMAT_PATTEN = "#0.00";
    public static String INTEGER_FORMAT_PATTEN = "#0";
    public static SecureRandom random = new SecureRandom();


    /**
     * 分 -> 元 ， 保留2位小数
     *
     * @param num
     * @return
     */
    public static BigDecimal toYuan(long num){
        BigDecimal b = new BigDecimal(Long.toString(num));
        BigDecimal hundred = new BigDecimal("100");
        return b.divide(hundred, DEFAULT_DIV_SCALE, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 分 -> 元, 向上取整
     *
     * @param num
     * @return
     */
    public static BigDecimal toYuanInteger(long num){
        BigDecimal b = new BigDecimal(Long.toString(num));
        BigDecimal hundred = new BigDecimal("100");
        return b.divide(hundred, INTEGER_SCALE, BigDecimal.ROUND_UP);
    }

    /**
     * 分 -> 元，保留2位小数
     *
     * @param num
     * @return
     */
    public static BigDecimal toYuan(BigDecimal num){
        if (num != null){
            BigDecimal hundred = new BigDecimal("100");
            return num.divide(hundred, DEFAULT_DIV_SCALE, BigDecimal.ROUND_HALF_UP);
        }
        return null;
    }

    /**
     * 分 -> 元，向上取整
     *
     * @param num
     * @return
     */
    public static BigDecimal toYuanInteger(BigDecimal num){
        if (num != null){
            BigDecimal hundred = new BigDecimal("100");
            return num.divide(hundred, INTEGER_SCALE, BigDecimal.ROUND_UP);
        }
        return null;
    }

    /**
     * 分 -> 元 ， 保留2位小数
     * （注：若结果为整数，则为 xx.0 ）
     *
     * @param num
     * @return
     */
    public static double toYuanDouble(long num){
        return toYuan(num).doubleValue();
    }

    /**
     * 分 -> 元，舍去小数位
     *
     * @param num
     * @return
     */
    public static long toYuanLong(long num){
        return toYuan(num).longValue();
    }

    /**
     * 分 -> 元 ，按格式需求显示金额字符串
     *
     * @param num
     * @param pattern
     * @return
     */
    public static String toYuanStr(long num,String pattern){
        return new DecimalFormat(pattern).format(toYuan(num));
    }

    /**
     * 分 -> 元 ，向上取整,按格式需求显示金额字符串
     *
     * @param num
     * @param pattern
     * @return
     */
    public static String toYuanStrInteger(long num,String pattern){
        return new DecimalFormat(pattern).format(toYuanInteger(num));
    }

    /**
     * 分 -> 元 ，保留2位小数，并格式化为 xx.00
     *
     * @param num
     * @return
     */
    public static String toYuanStr(long num){
        return toYuanStr(num, YUAN_FORMAT_PATTEN);
    }

    /**
     * 分 -> 元 ，向上取整，并格式化为 xx.00
     *
     * @param num
     * @return
     */
    public static String toYuanStrInteger(long num){
        return toYuanStrInteger(num, YUAN_FORMAT_PATTEN);
    }

    /**
     * 分 -> 元, 保留2位小数，并格式化为 xx.00
     *
     * @param num
     * @return
     */
    public static String toYuanStr(BigDecimal num){
        return new DecimalFormat(YUAN_FORMAT_PATTEN).format(toYuan(num));
    }

    /**
     * 分 -> 元, 向上取整，并格式化为 xx.00
     *
     * @param num
     * @return
     */
    public static String toYuanStrInteger(BigDecimal num){
        return new DecimalFormat(YUAN_FORMAT_PATTEN).format(toYuanInteger(num));
    }

    /**
     * 元 -> 分
     *
     * @param num
     * @return
     */
    public static BigDecimal toFen(String num){
        BigDecimal b = new BigDecimal(num);
        BigDecimal hundred = new BigDecimal("100");
        BigDecimal one = new BigDecimal("1");
        return b.multiply(hundred).divide(one, INTEGER_SCALE, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 元 -> 分
     *
     * @param num
     * @return
     */
    public static long toFenLong(double num){
        return toFen(Double.toString(num)).longValue();
    }

    /**
     * 元 -> 分
     *
     * @param num
     * @return
     */
    public static long toFenLong(String num){
        return toFen(num).longValue();
    }

    /**
     * 求百分比
     *
     * @param dividen 被除数
     * @param divisor 除数
     * @return
     */
    public static String toPercent(long dividen,long divisor){
        BigDecimal dividenDecimal = new BigDecimal(Long.toString(dividen));
        if (divisor == 0L){
            return "";
        }
        BigDecimal divisorDecimal = new BigDecimal(Long.toString(divisor));
        BigDecimal hundred = new BigDecimal("100");
        return dividenDecimal.multiply(hundred).divide(divisorDecimal,DEFAULT_DIV_SCALE,BigDecimal.ROUND_HALF_UP).toString() + "%";
    }

    /**
     * 小数转换为百分比
     *
     * @param num
     * @return
     */
    public static String toPercent(BigDecimal num){
        if (num != null){
            BigDecimal one = new BigDecimal("1");
            BigDecimal hundred = new BigDecimal("100");
            return num.multiply(hundred).divide(one,DEFAULT_DIV_SCALE,BigDecimal.ROUND_HALF_UP).toString() + "%";
        }
        return "";
    }

    /**
     * 提供精确的小数位四舍五入处理。
     *
     * @param v     需要四舍五入的数字
     * @param scale 小数点后保留几位
     * @return 四舍五入后的结果
     */
    public static double getDoubleValue(double v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b = new BigDecimal(Double.toString(v));
        BigDecimal one = new BigDecimal("1");
        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 提供精确的小数位四舍五入处理。
     *
     * @param v     需要四舍五入的数字
     * @return 四舍五入后的结果
     */
    public static int round(double v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b = new BigDecimal(Double.toString(v));
        BigDecimal one = new BigDecimal("1");
        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).intValue();
    }

    /**
     * 根据毫秒数，获得秒数
     *
     * @param millis
     * @return
     */
    public static long getSecbyMillis(long millis){
        return new BigDecimal(millis).divide(new BigDecimal("1000"), INTEGER_SCALE, BigDecimal.ROUND_HALF_UP).longValue();
    }

    /**
     * 获得一定范围区间的随机数
     *
     * @param min
     * @param max
     * @return
     */
    public static int getRandomNum(int min,int max){
        return random.nextInt(max-min+1)+min;
    }

    /**
     * 是否是数字
     * @param val
     * @return
     */
    public static boolean isNum(String val) {
        if (StringUtils.isEmpty(val)) {
            return false;
        }
        Pattern pattern = Pattern.compile("[0-9]*");
        Matcher isNum = pattern.matcher(val);
        if (isNum.matches()) {
            return true;
        }
        return false;
    }

    public static boolean isMobile(String val) {
        if (StringUtils.isEmpty(val)) {
            return false;
        }
        Pattern pattern = Pattern.compile("[0-9-]*");
        Matcher isNum = pattern.matcher(val);
        if (isNum.matches()) {
            return true;
        }
        return false;
    }

    /**
     * 求和
     *
     * @param list
     * @return
     */
    public static long sum(List<Long> list){
        long sum = 0L;
        for (long i : list){
            sum += i;
        }
        return sum;
    }

}
